home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 301-325 / disk_315 / surf / mergergb.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  8KB  |  324 lines

  1. /*
  2.  * This program, when called with arg "smith", tries to read smith.r, smith.g
  3.  * and smith.b, and write a combined raw data file acceptable to RAY2, called
  4.  * smith.tmp
  5.  */
  6. #include <stdio.h>
  7. #include "mytypes.h"
  8.  
  9. #define RED 0
  10. #define GRN 1
  11. #define BLU 2
  12. #define NumPrims 3 /* number of primary colors */
  13.  
  14. #define MakeID(a,b,c,d) ( ((a)<<24) | ((b)<<16) | ((c)<<8) | (d) )
  15.  
  16. #define ID_FORM MakeID('F','O','R','M')
  17. #define ID_ILBM MakeID('I','L','B','M')
  18. #define ID_BMHD MakeID('B','M','H','D')
  19. #define ID_CMAP MakeID('C','M','A','P')
  20. #define ID_CAMG MakeID('C','A','M','G')
  21. #define ID_BODY MakeID('B','O','D','Y')
  22.  
  23. #define ROUNDUP(x) ( ((x)+1) & (~1L) )
  24.  
  25. struct CHUNK {
  26.     unsigned long Id, Size;
  27. } Chunk;
  28.  
  29. struct BMHD {
  30.     short w,h,x,y;
  31.     char npl,mask,compress,pad1;
  32.     short transparentColor;
  33.     char xAspect,yAspect;
  34.     short pageWidth,pageHeight;
  35. };
  36.  
  37. /*
  38.  * compare width and height of two bit maps
  39.  * return false if equal
  40.  */
  41. bool CmpBMHD(a, b)
  42.     struct BMHD *a, *b;
  43. {
  44.     return( a->w != b->w ||
  45.             a->h != b->h ||
  46.           a->npl != b->npl
  47.           );
  48. }
  49.  
  50.  
  51. struct BMHD bmhd[NumPrims];
  52. static FILE *ftrip[NumPrims], *fout;
  53. char *nametrip[NumPrims];
  54. char *oname;
  55. bool FileError;
  56. short depth;
  57.  
  58. unsigned char colmap[NumPrims][32][3];
  59.  
  60.  
  61. /*
  62.  * read len bytes from selected file
  63.  */
  64. void FRead(buffer, len, filenum)
  65.     char *buffer;
  66.     int len, filenum;
  67. {
  68.     if( fread(buffer, len, 1, ftrip[filenum]) == 0 ) {
  69.         fprintf(stderr, "read error in %s\n", nametrip[filenum] );
  70.         exit(-1);
  71.     }
  72. }
  73.  
  74.  
  75.  
  76. #define ABORT(str) { fprintf(stderr,str); exit(-1); }
  77.  
  78. #define ReadChunk()  FRead(&Chunk, sizeof(Chunk), filenum)
  79.  
  80. void ReadIffHeaders(filenum)
  81.     int filenum;
  82. {
  83.     long    ILBMid;
  84.     bool cmapFlag = false,
  85.          bmhdFlag = false;
  86.     short i;
  87.  
  88.  
  89.     ReadChunk ();
  90.     if (Chunk.Id != ID_FORM)
  91.         ABORT ("Not an IFF File");
  92.  
  93.     FRead (&ILBMid, 4, filenum);
  94.     if (ILBMid != ID_ILBM)
  95.         ABORT ("Not an ILBM File");
  96.  
  97.     while (1) {
  98.         long camgdata;
  99.  
  100.         ReadChunk ();
  101.  
  102.         if (Chunk.Id == ID_BODY) {
  103.             if (!cmapFlag) {
  104.                 printf("no cmap before body in %s\n", nametrip[filenum]);
  105.                 FileError = true;
  106.             }
  107.             if (!bmhdFlag) {
  108.                 printf("no bmhd before the body in %s\n", nametrip[filenum]);
  109.                 FileError = true;
  110.             }
  111.             return;
  112.         }
  113.  
  114.         if( feof( ftrip[filenum] ) ) {
  115.             printf("reached end of file without seeing body in %s\n", nametrip[filenum]);
  116.             FileError = true;
  117.             return;
  118.         }
  119.  
  120.         switch (Chunk.Id) {
  121.             case ID_CMAP:
  122.                 FRead (colmap[filenum], Chunk.Size, filenum);
  123.                 for (i = 0; i < 32; i++) {
  124.                     colmap[filenum][i][filenum] >>= 4;
  125.                 }
  126.                 cmapFlag = true;
  127.                 break;
  128.             case ID_BMHD:
  129.                 FRead(&bmhd[filenum], Chunk.Size, filenum);
  130.                 bmhdFlag = true;
  131.                 break;
  132.             case ID_CAMG:
  133.                 FRead( &camgdata, sizeof(camgdata),filenum );
  134.                 break;
  135.             default:            /* unknown identifier */
  136.                 fseek( ftrip[filenum], Chunk.Size, 1);
  137.                 break;
  138.         }
  139.     }
  140. }
  141.  
  142.  
  143. /*
  144.  * leftmost pixel of byte is in most significant bit of byte
  145.  */
  146. static char GetIlbmVal( rastlist, h)
  147.     char *rastlist[6];
  148.     int h;
  149. {
  150.     int i;
  151.     char value = 0;
  152.     short mask, bytep;
  153.  
  154.     mask = 0x80 >> ( h & 7);
  155.     bytep = h >> 3;
  156.  
  157.     for( i = depth-1; i >= 0; i-- ) {
  158.         value <<= 1;
  159.         value |= (*(rastlist[i]+bytep) & mask) ? 1: 0;
  160.     }
  161.     return( value );
  162. }
  163.  
  164. /*
  165.  * decompress a runlength row of bytes
  166.  */
  167. static void ReadDecomLine(linebytes, rp, filenum)
  168.     int linebytes, filenum;
  169.     char *rp;
  170. {
  171.     int runlen;
  172.     char pixel;
  173.  
  174.     while (linebytes) {
  175.         runlen = getc (ftrip[filenum]);
  176.         if (runlen > 127)
  177.             runlen -= 256;
  178.         if (runlen >= 0) {
  179.             runlen++;
  180.             FRead (rp, runlen, filenum);
  181.             rp += runlen;
  182.             linebytes -= runlen;
  183.         }
  184.         else {
  185.             runlen = -runlen + 1;
  186.             linebytes -= runlen;
  187.             pixel = getc (ftrip[filenum]);
  188.             do
  189.                 *(rp++) = pixel;
  190.             while (--runlen);
  191.         }
  192.     }
  193. }
  194. /*
  195.  * read raster line from one of the color files
  196.  */
  197. void LoadRaster(raster, ByteWidth, filenum)
  198.     char *raster[6];
  199.     int ByteWidth, filenum;
  200. {
  201.     if(bmhd[filenum].compress = 0) {
  202.         FRead (raster, ByteWidth * depth, filenum);
  203.     }
  204.     else {
  205.         short i;
  206.         for( i = 0; i < depth; i++) {
  207.             ReadDecomLine( ByteWidth, raster[i], filenum);
  208.         }
  209.     }
  210. }
  211.  
  212. /*
  213.  * write intensity values for a given gun
  214.  * note: I've made dirty assumption about byte ordering in a short word
  215.  * if you run this on an ibm (ha ha ha) you'll have to change it
  216.  */
  217. #define ChipSize 4
  218. void SaveRaster( raster, width, prim)
  219.     char *raster[];
  220.     int width, prim;
  221. {
  222.     short i, j;
  223.     unsigned short val;
  224.  
  225.     for( i = 0; i < width; i += ChipSize ) {
  226.         val = colmap[prim][GetIlbmVal(raster, i+3)][prim] << ChipSize;
  227.         val |= colmap[prim][GetIlbmVal(raster, i+2)][prim];
  228.         fputc( val&0xff, fout);
  229.         val = colmap[prim][GetIlbmVal(raster, i+1)][prim] << ChipSize;
  230.         val |= colmap[prim][GetIlbmVal(raster, i+0)][prim];
  231.         fputc( val&0xff, fout);
  232.     }
  233. }
  234.  
  235. /*
  236.  * translate body of file to format RAY2 likes
  237.  */
  238. void TranslateRay2Body()
  239. {
  240.     int BytesWidth;
  241.     int row, height, width, plane, prim;
  242.     char *raster[6];
  243.  
  244.     depth = bmhd[0].npl;
  245.     width = bmhd[0].w;
  246.     height = bmhd[0].h;
  247.     BytesWidth = (width + 7)/8 ;
  248.  
  249.     for( plane = 0; plane < bmhd[0].npl; plane++ ) {
  250.         raster[plane] = (char *)malloc(BytesWidth);
  251.     }
  252.  
  253.     for( row = 0; !FileError && row < height; row++ ) {
  254.         fputc((unsigned char)(row>>8),fout);      /* write line number */
  255.         fputc((unsigned char)(row&0xff),fout);
  256.  
  257.         for( prim = RED; prim <= BLU; prim++ ) {
  258.             LoadRaster( raster, BytesWidth, prim);
  259.             SaveRaster( raster, width, prim);
  260.         }
  261.     }
  262. }
  263.  
  264.  
  265.  
  266. main(argc, argv)
  267.     int argc;
  268.     char *argv[];
  269. {
  270.     char buff[4][80];
  271.     char *extensions = "rgb";
  272.     int i;
  273.  
  274.     if( argc == 1 || *argv[1] == '?' ) {
  275.         fprintf(stderr,"usage:  merge filename\n");
  276.         exit(-1);
  277.     }
  278.     FileError = false;
  279.  
  280.     for( i = 0; i < NumPrims; i++ ) {
  281.         sprintf(buff[i], "%s.%c", argv[1], extensions[i]);
  282.         nametrip[i] = buff[i];
  283.         ftrip[i] = fopen(nametrip[i],"r");
  284.         if(!ftrip[i]) {
  285.             fprintf(stderr,"unable to read %s\n", nametrip[i]);
  286.             FileError = true;
  287.         }
  288.     }
  289.  
  290.     sprintf(buff[3], "%s.tmp", argv[1]);
  291.     oname = (argc>2)? argv[2]: buff[3];
  292.     fout = fopen( oname,"w");
  293.     if(!fout) {
  294.         fprintf(stderr,"unable to write to %s\n", oname);
  295.         FileError = true;
  296.     }
  297.  
  298.     if( FileError ) goto ErrorExit;
  299.  
  300.     for( i = 0; i < NumPrims; i++ ) {
  301.         printf("reading header %d\n", i);
  302.         ReadIffHeaders(i);
  303.     }
  304.  
  305.     for( i = 1; i < NumPrims; i++ ) {
  306.         if( CmpBMHD(&bmhd[0], &bmhd[i])) {
  307.             fprintf(stderr,"image sizes differ(r != %d)\n", i);
  308.             FileError = true;
  309.         }
  310.     }
  311.  
  312.     if( FileError ) goto ErrorExit;
  313.     printf("about to translate body\n");
  314.     TranslateRay2Body();
  315.  
  316.     ErrorExit:
  317.         for( i = 0; i < NumPrims; i++) {
  318.             if(ftrip[i]) fclose( ftrip[i] );
  319.         }
  320.         if(fout) fclose(fout);
  321. }
  322.  
  323.  
  324.